this._timerId = 0;
this._timeChangeId = 0;
this._clockOffsetSecs = 0;
+ this._ignoreClockOffsetChanges = false;
// Start tracking timings
this._updateSettings();
this._clockOffsetSecs = this._getClockOffset();
try {
this._timeChangeId = this._clock.timeChangeNotify(() => {
+ if (this._ignoreClockOffsetChanges)
+ return GLib.SOURCE_CONTINUE;
+
const newClockOffsetSecs = this._getClockOffset();
const oldClockOffsetSecs = this._clockOffsetSecs;
}
async _onPrepareForSleep(preparingForSleep) {
- // Just come back from sleep, so take another inhibitor.
- if (!preparingForSleep)
+ // Just come back from sleep, so take another inhibitor. Also update
+ // the clock offset to account for the monotonic clock not advancing
+ // during sleep.
+ if (!preparingForSleep) {
this._ensureInhibitor();
+ this._clockOffsetSecs = this._getClockOffset();
+ this._ignoreClockOffsetChanges = false;
+ }
try {
await this._updateUserState(true);
console.warn(`Failed to update user state: ${e.message}`);
}
- // Release the inhibitor if we’re preparing to sleep.
- if (preparingForSleep)
+ // Release the inhibitor if we’re preparing to sleep. Also avoid
+ // adjusting the time due to offset changes caused by the monotonic
+ // clock not advancing during sleep until we have updated the current
+ // offset to account for this.
+ if (preparingForSleep) {
+ this._ignoreClockOffsetChanges = true;
this._releaseInhibitor();
+ }
}
/** Shut down the state machine and write out the state file. */
time: TestHarness.timeStrToSecs(timeStr),
newPreparingForSleepState: true,
});
+ this._insertEvent({
+ type: 'time-change',
+ time: TestHarness.timeStrToSecs(timeStr) + 1,
+ newTime: TestHarness.timeStrToSecs(timeStr) + duration - 1,
+ callback: null,
+ });
this._insertEvent({
type: 'preparing-for-sleep-state-change',
time: TestHarness.timeStrToSecs(timeStr) + duration,
'dailyLimitTime': TestHarness.timeStrToSecs('2024-06-01T17:00:00Z'),
});
+ // Ensure the suspend event caused a state change to inactive and its
+ // time was not adjusted due to offset changes on resume
+ harness.addAssertionEvent('2024-06-01T15:00:02Z', () => {
+ const [, historyContents] = harness.mockHistoryFile.load_contents(null);
+ expect(JSON.parse(new TextDecoder().decode(historyContents)))
+ .withContext('History file contents')
+ .toContain({
+ 'oldState': UserState.ACTIVE,
+ 'newState': UserState.INACTIVE,
+ 'wallTimeSecs': TestHarness.timeStrToSecs('2024-06-01T12:00:01Z'),
+ });
+ });
+
harness.shutdownManager('2024-06-01T15:20:00Z', timeLimitsManager);
harness.run();